﻿/******************************************************************
* 项目名称 ：TorrentDHT 
* 项目描述 ： 
* 类 名 称 ：SimpleTracker 
* 类 描 述 ： 
* CLR 版本 ：4.0.30319.42000 
* 版权所有 ：袁振峰
* 联系方式 ：http://www.ustuy.com/ 
******************************************************************/
using MonoTorrent.Common;
using MonoTorrent.TorrentWatcher;
using MonoTorrent.Tracker;
using MonoTorrent.Tracker.Listeners;
using System;
using System.Configuration;
using System.Diagnostics;
using System.IO;

namespace SampleTracker
{
    public class SimpleTracker
    {
        Tracker tracker;
        TorrentFolderWatcher watcher;
        const string TORRENT_DIR = "Torrents";

        public SimpleTracker()
        {
            System.Net.IPEndPoint listenpoint = new System.Net.IPEndPoint(System.Net.IPAddress.Loopback, 40068);
            Console.WriteLine("Listening at: {0}", listenpoint);
            ListenerBase listener = new HttpListener(listenpoint);
            tracker = new Tracker();
            tracker.AllowUnregisteredTorrents = true;
            tracker.RegisterListener(listener);
            listener.Start();

            SetupTorrentWatcher();


            while (true)
            {
                System.Threading.Thread.Sleep(10000);
            }
        }

        private void SetupTorrentWatcher()
        {
            watcher = new TorrentFolderWatcher(Path.GetFullPath(TORRENT_DIR), "*.torrent");
            watcher.TorrentFound += delegate (object sender, TorrentWatcherEventArgs e)
            {
                try
                {
                    // This is a hack to work around the issue where a file triggers the event
                    // before it has finished copying. As the filesystem still has an exclusive lock
                    // on the file, monotorrent can't access the file and throws an exception.
                    // The best way to handle this depends on the actual application. 
                    // Generally the solution is: Wait a few hundred milliseconds
                    // then try load the file.
                    System.Threading.Thread.Sleep(500);

                    Torrent t = Torrent.Load(e.TorrentPath);

                    // There is also a predefined 'InfoHashTrackable' MonoTorrent.Tracker which
                    // just stores the infohash and name of the torrent. This is all that the tracker
                    // needs to run. So if you want an ITrackable that "just works", then use InfoHashTrackable.

                    // ITrackable trackable = new InfoHashTrackable(t);
                    ITrackable trackable = new CustomITrackable(t);

                    // The lock is here because the TorrentFound event is asyncronous and I have
                    // to ensure that only 1 thread access the tracker at the same time.
                    lock (tracker)
                        tracker.Add(trackable);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("Error loading torrent from disk: {0}", ex.Message);
                    Debug.WriteLine("Stacktrace: {0}", ex.ToString());
                }
            };

            watcher.Start();
            watcher.ForceScan();
        }
    }
}
